Rule and RuleTemplate file format conversion#5572
Conversation
|
This pull request has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/rules-and-rule-templates-yaml-integration/168568/304 |
|
@openhab/core-maintainers I'm not able to figure out why the JavaDoc check fails. I've built I see a number of errors in the build log similar to this, but I don't know what this PR does to affect that, or why it expects Error: Error fetching link: /home/runner/work/openhab-core/openhab-core/bom/compile/target/site/apidocs. Ignored it.
Error: Error fetching link: /home/runner/work/openhab-core/openhab-core/bom/test/target/site/apidocs. Ignored it. |
|
I think I found and fixed the JavaDoc problems, they weren't exactly easy to find. For future reference, I used this command to find them: mvn javadoc:javadoc -X -Dshow=protected -pl :org.openhab.core.automation |
|
@lolodomo Here it is: Have at it 😉 |
|
I must update this PR to accommodate #5462. Hopefully, it won't require large changes. |
|
The changes to adjust to #5462 were simple except that now I can't get the formatter to behave properly regarding indentation. Having two optional sections have made it more complicated to handle indentation, and the result is that indentation is largely missing after having processed a rule without a trigger. I've tried asking Google's "AI" for hints, because this is largely black magic to me - I have no idea how to actually debug what the formatter does and why. But, as usual, what I get is mostly not working or pure BS. Anything I've tried seems to have made it consistently worse. |
|
It seems like indentation collapses after it has parsed one triggerless rule. Please note that the action indentation isn't handled by the formatter (I replace the whole "script part" post formatting, because otherwise it would completely reformat the code), so it is unaffected - triggers and conditions however are unindented after processing the triggerless rule: Result |
|
I don't know what to do about the formatting. I've tried everything I can think of, even trying to get input from both Google's "AI" and Copilot. They both suggest basically the same things, which don't work. It seems like whenever a rule without a trigger is encountered, the "indentation tracker" errors and the following rules are without indentation. Copilot even suggested that this might be a bug in Xtext, and I've had the same thought. Individually, rules are formatted correctly, but when several are exported "together", the rules that follow a rule without a trigger are basically without indentation. This shouldn't "be possible" to achieve simply by doing something wrong in the formatter. Indentations are all relative, I've found no way to set an absolute indentation. When there is a trigger, indentation is increased after "when" and then decreased before "then". Then it's increased again after "then" and decreased before "end". But, when there's no trigger, the first "rule" it will meet is the decrement before "then" - but it's already at indentation level 0 at that point. The bug might therefore be a result of the indentation "becoming negative". If we could set absolute indentation levels, we could set it to 0 before "then" and avoid the whole problem, but that doesn't seem to be an option. We're running Xtext 2.43.0.M2, which isn't a proper release. I'm questioning if it's a good idea to run milestone/snapshot versions, but for all I know, the behavior is the same in 2.42.0. I don't know how to test that without building core in its entirety, so I haven't done so. I'll push the updated code despite the formatting problems. I doubt that they are directly related to this PR, so I suggest that the PR is reviewed despite this problem. |
|
Review in progress. |
|
The Java25 build failure seems to be caused by flaky integration tests, the Java21 build passed, and I've changed nothing in the failing bundle in the latest commit. It seems like I was able to fix the formatter with a little bit of "hacking". I converted the formatter from Xtext to Java, so that I have any idea of what I'm doing. I then overrode parts of the underlying logic so that I got access to where the indentation level go negative (it was indeed the problem). I then simply make it never go below 0, and the problem appears to be gone 🥳 Result |
|
@lolodomo I force pushed just the last commit (unchanged) to trigger a rebuild because of the Java25 build failure. I hope that doesn't interfere with your review. It shouldn't, given that I pushed that commit a short while ago, and I doubt that you have started reviewing anything from that commit 🙏 |
|
I had to push one more change. This is the reason why I've waited with creating this PR, I figure out what changes must be done to the REST API while I develop the UI code. I hope that there won't be any further changes needed, the UI work is almost completed. This change is "a bit dodgy". On the The "dodgy part" is that, this endpoint allows querying the "summary" even if the user isn't an admin. I suppose that there has been some kind of security consideration mixed in here: if ((summary == null || !summary) && !securityContext.isUserInRole(Role.ADMIN)) {
// users may only access the summary
return JSONResponse.createErrorResponse(Status.UNAUTHORIZED, "Authentication required");
}The "problem" now is that by adding If So, is it OK to include |
|
I just realized, that in DSL Rules in trigger |
This should be checked, however I don't have this branch checked out now, so I can't see how it behaves. Because of the Californium issue I can't really check this branch out without making a mess locally either, because this branch still uses the "M6 version" of Californium 4. But, I can't rebase the branch either, because @lolodomo has started to review. I think I must wait for the review to finish, then rebase, and then verify how this is handled. |
This does not matter. Two-digits hours are required only by the DSL Rules.xtext parser. |
| * @author Ravi Nadahar - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| @Component(immediate = true, service = { RuleSerializer.class, RuleParser.class }) |
There was a problem hiding this comment.
immediate = true means that the component will be activated, even if it is not used during the openHAB execution. Can immediate = true be removed, so that the converter is activated, only when requested? Likewise for immediate = true in YamlRuleConverter.
service={ RuleSerializer.class, RuleParser.class } can be skipped, because by default its value are the directly implemented interfaces of the class. In some other places in openHAB services= is skipped and its default value applied.
There was a problem hiding this comment.
I've annotated the classes in the same way that other "corresponding" components are annotated. Without immediate, the service won't start until it's requested, and I don't know exactly what that will mean here. I assume that it means that it will be started when FileFormatResource is started, which is, as far as I know, at startup.
So, it looks like it should work without immediate = true, but I think it should "stay the same" as the other converters, like DslThingConverter, YamlThingConverter, DslThingConverter etc.
When it comes to not declaring a service, I think that relying on "magical behavior" is bad, and frankly, I don't think OSGi should have done it this way. Whether a class extends another class or implements an interface can be somewhat coincidental, but will have consequences for the "magical behavior". It can even change when code is refactored, and if the person doing the refactoring aren't aware of the "magical behavior", it will constitute a bug. Another thing is that if you for some reason adds another interface that is implemented, like a listener interface, it will also be registered as a service for that. This alone is a good reason why all components should be explicitly declared regarding services IMO.
I also find it helpful to just look at a component declaration and know what services it registers, instead of having to know the rules of the "magical behavior" by heart. I simply think that it's better when it is declared, and there's nothing to "save" by not declaring it.
|
@lolodomo How is your review going? This PR needs a rebase to be adapted to other PRs that have been merged. |
|
I plan to finish my review this week. |
|
@Nadahar : can you please rebase ? |
…e templates Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
It took some work to adjust to the changes, especially in |
| @RolesAllowed({ Role.ADMIN }) | ||
| @Path("/rules") | ||
| @Consumes(MediaType.APPLICATION_JSON) | ||
| @Produces({ "application/vnd.openhab.dsl.rule", "application/yaml", MediaType.APPLICATION_JSON }) |
There was a problem hiding this comment.
MediaType.APPLICATION_JSON to be removed
There was a problem hiding this comment.
No, it returns JSON in case of errors. That is so that the error can be parsed by the other side.
| @RolesAllowed({ Role.ADMIN }) | ||
| @Path("/ruletemplates") | ||
| @Consumes(MediaType.APPLICATION_JSON) | ||
| @Produces({ "application/yaml", MediaType.APPLICATION_JSON }) |
There was a problem hiding this comment.
MediaType.APPLICATION_JSON to be removed
There was a problem hiding this comment.
No, it returns JSON in case of errors. That is so that the error can be parsed by the other side.
| @Consumes({ MediaType.APPLICATION_JSON }) | ||
| @Produces({ "text/vnd.openhab.dsl.thing", "text/vnd.openhab.dsl.item", "text/vnd.openhab.dsl.sitemap", | ||
| "application/yaml" }) | ||
| @Produces({ "text/vnd.openhab.dsl.thing", "text/vnd.openhab.dsl.item", "application/vnd.openhab.dsl.rule", |
There was a problem hiding this comment.
Why is it "application" for rules while "text" for all others ?
There was a problem hiding this comment.
The MIME/media type rules are strange and confusing - there were/are? an authority that assigns them, and everybody was supposed to register one before using it. But, that went wrong a loong time ago, so I'm betting that there are more unofficial than official ones in use. The were originally used for e-mail content and attachment description.
Many seem quite random to me, and if you read the "definition", it isn't exactly clear:
- text: Indicates human-readable data (e.g., text/plain, text/html, text/css). The system assumes the content is strictly character-based and can be read directly by text editors.
- application: The "catch-all" category for structured data, executable code, or binary data that does not fit neatly into other types (e.g., application/json, application/pdf, application/zip).
Both YAML and JSON use application for example, so it's hard to say exactly where the limit between a "text document" and "structured data" goes. And, why e.g HTML is text while JSON is application is anybody's guess I think. I'm sure it made sense to some person at some point.
In the end, it doesn't really matter. They are just strings that identify different kind of content, and as long as we use it consistenly, they will "work" for identification purposes. I didn't come up with the "OH MIME-types", so you'd better address the question to whoever made the decsision 😉
There was a problem hiding this comment.
I think perhaps the distinction is what can be used in the "body" of an e-mail and what must be an attachment. In that case, I guess all the "OH types" should have been application.
There was a problem hiding this comment.
It was discussed when I first implemented the API and it was decided that "text" is better.
Will try the find the discussion.
I don't really care myself but what annoys me is to have something different for rules. Makes no sense.
And changing now for others will certainly break Main UI.
There was a problem hiding this comment.
I don't find the discussion. @mherwege I am almos certain you were involved, do you remember?
There was a problem hiding this comment.
I don't find the discussion. @mherwege I am almos certain you were involved, do you remember?
I don't remember discussion text vs application. The only thing I can find is this: #4630 (comment)
There was a problem hiding this comment.
I don't think we should change it now in any case, changing things like that is just asking for things to break. As said above, I just consider these strings "codes" for identifying content types, and as long as everybody use the same code for the same content, the code itself doesn't really matter.
Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
|
These random test failures are a bit annoying, and I've seen the "audio" failure quite a lot lately. I can't see any relevant changes to the bundle... |
|
I looked a bit at the failing test, and I can't quite pin down what happens. The failure seems to be mostly on Java 25, but by looking at It seems like there is a path where |

This PR implements
RuleandRuleTemplatefile format conversion in core. It provides the necessary REST endpoints, and the underlying changes required to provide the REST endpoints.Much probably needs to be said/explained, which we'll have to get back to. The commits are "logical units" and their description should indicate what the particular change is about.
I'm creating it as a draft until any build issues are resolved, since I have not done a full test build of the final state locally.